//
//  CarModelsViewModel.swift
//  Automobile
//
//  Created by erkebulan elzhan on 9/3/20.
//  Copyright © 2020 erkebulan elzhan. All rights reserved.
//

import Foundation

final class CarModelsViewModel {
    
    var delegate: ViewModelProtocol!
    
    var carData: CarData!
    
    var data: [Models] = []
    
    var filteredData: [Models] = [] {
        didSet {
            self.delegate.updatePosts()
        }
    }
    
    var resultDelegate: ResultsVCDelegate?
    
    var isCreateCarSection: Bool {
        return resultDelegate is SelectCarViewController
    }
    
    var lastSelectedID: Int?
    
    private let backendService = Backend()
}


// MARK: - Network

extension CarModelsViewModel {
    
    func loadModels () {
        
        let parameters:[URLQueryItem] = [URLQueryItem(name: "mark_id", value: "\(carData.marka!.id)")]
        let request = URLRequest(url: Request(base: carData.saveToGarage ? .garage : .advert, parameters: parameters).getUrl(path: "cars/models"))
        
        self.delegate.updateSpinner(showSpinner: true)
        
        backendService.fetchFromBackend(for: Response<[ModelModel]>.self, request: request, statusCode: 200) { (result) in
            self.delegate.updateSpinner(showSpinner: false)
            
            switch result {
                case .failure(let error):
                    self.delegate.didHappenError(error: error)
                case .success(let data):
                    self.handleLoadedData(data: data)
                    self.loadPopular()
            }
        }
    }
    
    func loadPopular () {
        
        let parameters: [URLQueryItem] = [URLQueryItem(name: "mark_id", value: "\(carData.marka!.id)")]
        
        let requestURL = Request(base: carData.saveToGarage ? .garage : .advert, limit: 4, parameters: parameters).getUrl(path: "cars/models")
        let request = URLRequest(url: requestURL)
        
        backendService.fetchFromBackend(for: Response<[ModelModel]>.self, request: request, statusCode: 200) { (result) in
            switch result {
            case .failure(let err):
                self.delegate.didHappenError(error: err)
            case .success(let response):
                self.handlePopular(data: response.results)
            }
        }
    }
    
}

// MARK: - Methods

extension CarModelsViewModel {
    
    public func updateCheckBoxes (indexPath: IndexPath) {
        let wrapper = [data, filteredData].map { (container:[Models]) -> [Models] in
            
            // Copy which is muttable
            var copy = container
            
            for (i, el) in copy.enumerated() {
                let index = el.items.firstIndex(where: { x -> Bool in
                    x.id == filteredData[indexPath.section].items[indexPath.row].id
                })
                
                // Update Selection
                if (index != nil) {
                    copy[i].items[index!].isSelected.toggle()
                }
                
                // Remove Last Selection, if only single selection is supported
                if isCreateCarSection && lastSelectedID != nil {
                    let _index = el.items.firstIndex(where: {x -> Bool in
                        x.id == lastSelectedID!
                    })
                    if _index != nil {
                        copy[i].items[_index!].isSelected.toggle()
                    }
                }
            }
            
            return copy
        }
        
        data = wrapper[0]
        filteredData = wrapper[1]
        lastSelectedID = filteredData[indexPath.section].items[indexPath.row].id
    }
    
    public func updateSearch (text: String?) {
        if let _text = text {
            var dataCopy = data
            dataCopy[1].items = data[1].items.filter {
                $0.name.lowercased().contains(_text)
            }
        } else {
            filteredData = data
        }
    }
    
    public func getModelsData () -> [Model] {
        var models:[Model] = []
        
        for item in data[1].items {
            if item.isSelected {
                models.append(item.model)
            }
        }
        
        return models
    }
    
    private func handleLoadedData (data: Response<[ModelModel]>) {
        let container = [Models(name: "Популярные", items: []), Models(name: "Все", items: data.results)]
        self.data = container
        self.filteredData = container
    }
    
    private func handlePopular (data: [ModelModel]) {
        if self.data.count >= 2 {
            self.data[0].items = data
        }
        
        if self.filteredData.count >= 2 {
            self.filteredData[0].items = data
        }
        
        self.delegate.updatePosts()
    }
}

